<template>
  <div>
    <slot name="items"></slot>
  </div>
</template>
<script>
/**
 * author：ronggang
 * email：suntework@163.com
 */
export default {
  name: 'vant-form',
  data() {
    return {
      rulesEles: []
    };
  },
  props: ['inputVail', 'rules'],
  mounted() {
    // 递归获取所有带有 rule 属性的元素
    this.rulesEles = this.getRuleEle(this.$slots.items);
    // 处理 输入监听的校验
    if (this.inputVail) this.eleSetInput();
  },
  methods: {
    // 递归获取插槽内所有拥有 input 属性的元素【内部方法】
    getRuleEle(eleObj) {
      const childs = [];
      if (!eleObj) return;
      // 循环所有元素（兼容 对象和数组的情况）
      // eleObj = eleObj instanceof Array ? eleObj : [eleObj];
      eleObj.forEach(function (ele) {
        const item = ele;
        if (ele.data && ele.data.attrs.rule) {
          item.elm.getElementsByClassName('van-field__error-message')[0].style.display = 'none';
          childs.push(ele);
        }
        ele.children && childs.push.apply(childs, this.getRuleEle(ele.children));
      });
      return childs;
    },
    // 设置 需要校验的属性 的 input监听 校验 【内部方法】
    eleSetInput() {
      const self = this;
      try {
        self.rulesEles.forEach(function (item) {
          const inputEle = item.elm.getElementsByTagName('input')[0];
          inputEle.oninput = function () {
            // 输入实时校验
            self.handleVail(item);
          };
        });
      } catch (e) {
        console.error(e);
      }
    },
    // 检验元素的值是否满足条件（参数：索引值 ）【内部方法】
    handleVail(handleEle) {
      const item = handleEle;
      try {
        const self = this;
        // 获取元素下 input 元素（目前只针对 单个输入框做处理）
        const inputValue = handleEle.elm.getElementsByTagName('input')[0].value;
        let vailFlag = true;
        // 获取设置的校验规则
        const ruleObj = self.rules ? self.rules[handleEle.data.attrs.rule] : null;
        if (!ruleObj) return vailFlag;
        // 非空校验
        vailFlag = ruleObj.required ? !!inputValue : vailFlag;
        // 正则校验
        vailFlag = ruleObj.regExp ? ruleObj.regExp.test(inputValue) && vailFlag : vailFlag;
        // 用户自定义校验
        vailFlag = typeof ruleObj.handleVailFun === 'function' ? ruleObj.handleVailFun(inputValue) && vailFlag : vailFlag;
        console.log(handleEle);
        // 获取组件实例，修改错误信息(注释的代码可以实现效果，但是违反了子组件修改父组件的规则)
        // handleEle.componentInstance.errorMessage = vailFlag?'':ruleObj.errorMessage;
        // 目前是通过控制元素显示隐藏去实现错误信息的展示
        if (!vailFlag) item.elm.getElementsByClassName('van-field__error-message')[0].style.display = 'block';
        else item.elm.getElementsByClassName('van-field__error-message')[0].style.display = 'none';
        return vailFlag;
      } catch (e) {
        console.error(e);
        return false;
      }
    },
    // 整体校验【对外提供方法】
    allVail() {
      let vailFlag = true;
      this.rulesEles.forEach(function (item) {
        vailFlag = !item ? false : vailFlag && true;
      });
      return vailFlag;
    }
  }
};
</script>
<style>
</style>
